package cn.ucox.web.ms.service.impl;


import cn.ucox.web.ms.components.ftp.DexFtpClient;
import cn.ucox.web.ms.components.ftp.FTPClientPool;
import cn.ucox.web.ms.components.ftp.FtpConfig;
import cn.ucox.web.ms.config.AppConstant;
import cn.ucox.web.ms.config.DataExchangeConfig;
import cn.ucox.web.ms.monitor.SyncFileParser;
import cn.ucox.web.ms.redis.RedisClient;
import cn.ucox.web.ms.service.ITecentUserConfirmService;
import cn.ucox.web.ms.util.*;
import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.pool2.PooledObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

import javax.annotation.Resource;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

import static cn.ucox.web.ms.monitor.SyncFileParser.SYNC_FTP_FILE_INDEX;

//import org.bouncycastle.util.encoders.Base64;

/**
 * @author wuzy
 * @created 2017-04-27-09:10
 * @email wzy@oceansoft.com.cn
 */
@Service
public class TecentUserConfirmImpl implements ITecentUserConfirmService {

    private static final Logger logger = LoggerFactory.getLogger(TecentUserConfirmImpl.class);

    private ConfigurableApplicationContext context;

    private SyncFileParser syncFileParser;

    @Resource
    private DataExchangeConfig.FtpConfigHub ftpConfigHub;


    @Resource
    private DexFtpClient dexFtpClient;

    @Resource
    private DexFtpClient dexFtpClientN;

    private RedisClient redisClient = RedisClient.instance();

    //提供腾讯实名核身的最高帧接口
    @Override
    public ResultTecent InsertLukex(Map<String, String> map) {

        ResultTecent apiResult = new ResultTecent();
        PooledObject<FTPClient> pooledObject = null;
        PooledObject<FTPClient> pooledObjectN = null;
        try {
            //每一条 Request 的唯一 token 标识
            String token = "";
            if (!StringUtils.isBlank(map.get("token"))) {
                token = map.get("token");
            } else {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS03));
                apiResult.setErrormsg("请求缺少必要参数token");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            //用户标识
            String uid = "";
            if (!StringUtils.isBlank(map.get("uid"))) {
                uid = map.get("uid");
            } else {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS03));
                apiResult.setErrormsg("请求缺少必要参数uid");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            //时间戳
            String timestamp = "";
            if (!StringUtils.isBlank(map.get("timestamp"))) {
                timestamp = map.get("timestamp");
            } else {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS03));
                apiResult.setErrormsg("请求缺少必要参数timestamp");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            //项目标识 appid
            String appid = "";
            if (!StringUtils.isBlank(map.get("appid"))) {
                appid = map.get("appid");
            } else {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS03));
                apiResult.setErrormsg("请求缺少必要参数appid");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            //随记参数 randomstr
            String randomstr = "";
            if (!StringUtils.isBlank(map.get("randomstr"))) {
                randomstr = map.get("randomstr");
            } else {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS03));
                apiResult.setErrormsg("请求缺少必要参数randomstr");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            //上述参数使用“-”按给定顺序拼接，拼接 后的字符串，再最后拼 接上“keys”,然后字符 串 md5，取 32 位小写 字符串（不需要图片 base64）
            String sign = "";
            if (!StringUtils.isBlank(map.get("sign"))) {
                sign = map.get("sign");
            } else {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS03));
                apiResult.setErrormsg("请求缺少必要参数sign");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            String datastr = "";
            if (!StringUtils.isBlank(map.get("data"))) {
                datastr = map.get("data");
            } else {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS03));
                apiResult.setErrormsg("请求缺少必要参数data");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            byte[] databyte = null;
            String datadecodestr = "";
            try {
                databyte = Base64.decode(datastr.getBytes("UTF-8"));
                //通过AES解密
                datadecodestr = AES256.Aes256Decode(databyte);
                //datadecodestr= String.valueOf(databyte);
            } catch (Exception ex) {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS11));
                apiResult.setErrormsg("其他内部错误");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            JSONObject dataobject = JSONObject.parseObject(datadecodestr);
            String Imageroll = "";
            if (!StringUtils.isBlank(dataobject.getString("Imageroll"))) {
                Imageroll = dataobject.getString("Imageroll");
            } else {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS06));
                apiResult.setErrormsg("必要参数丢失(Imageroll)");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            String idcard = "";
            if (!StringUtils.isBlank(dataobject.getString("idcard"))) {
                //身份证验证
                if (VerificationUtil.checkIdCard(dataobject.getString("idcard"))) {
                    idcard = dataobject.getString("idcard");
                } else {
                    apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS06));
                    apiResult.setErrormsg("身份验证失败(idcard)");
                    apiResult.setData("");
                    apiResult.setEntirety_time("");
                    apiResult.setLib_time("");
                    return apiResult;
                }
            } else {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS06));
                apiResult.setErrormsg("必要参数丢失(idcard)");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            String name = "";
            if (!StringUtils.isBlank(dataobject.getString("name"))) {
                name = dataobject.getString("name");
            } else {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS06));
                apiResult.setErrormsg("必要参数丢失(name)");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            //判断token是否失效
            //OiTecentSmhs oiTecentSmhs1=iTecentMapper.selectSMHS(token,randomstr,timestamp);
//            if(oiTecentSmhs1!=null)
//            {
//                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS05));
//                apiResult.setErrormsg("token已失效");
//                apiResult.setData("");
//                apiResult.setEntirety_time("");
//                apiResult.setLib_time("");
//                return apiResult;
//            }
            //验证sign
            String signstr = token + "-" + datastr + "-" + uid + "-" + timestamp + "-" + appid + "-" + randomstr + "-" + "keys";
            if (!Md5.stringToMD5(signstr).equals(sign)) {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS05));
                apiResult.setErrormsg("sign校验失败");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
            OiTecentSmhs oiTecentSmhs = new OiTecentSmhs();
            oiTecentSmhs.setGuid(UUID.randomUUID().toString());
            oiTecentSmhs.setToken(token);
            oiTecentSmhs.setUid(uid);
            oiTecentSmhs.setTimestamp(timestamp);
            String createstr = stampToDate(timestamp);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date datestr = sdf.parse(createstr);
            oiTecentSmhs.setCreatetime(datestr);
            oiTecentSmhs.setAppid(appid);
            oiTecentSmhs.setSign(sign);
            oiTecentSmhs.setData(datadecodestr);
            //String Imagerollbyte=Base64.toBase64String(Imageroll.getBytes("UTF-8"));
            //oiTecentSmhs.setImageroll(Imagerollbyte);
            oiTecentSmhs.setIdcard(idcard);
            oiTecentSmhs.setName(name);
            oiTecentSmhs.setTemp1(randomstr);
            oiTecentSmhs.setTemp2("");
            //int i= iTecentMapper.instertSMHS(oiTecentSmhs);
            String jsonstr = JSONObject.toJSONString(oiTecentSmhs);

            Long transId = Calendar.getInstance().getTimeInMillis();
            String fragNum = "1";
            int transDataLen = jsonstr.getBytes().length;
            String fileName = String.format("%s_%s_%s_%s.dex", transId, fragNum, 0, transDataLen);
            //transactionDataSlicer = new TransactionDataSlicer(outInWrite1Config, new DexFtpClient(outInWrite1Config));
            pooledObject = dexFtpClient.get();
            byte[] fragDataBuffer = jsonstr.getBytes();
            //将数据生成为dex文件上传到FTP，并同步到内网；
            boolean rt = pooledObject.getObject().appendFile(fileName, new ByteArrayInputStream(fragDataBuffer));
            //请求超时
            boolean boltrue = true;
            String data = "";
            Date date1 = new Date();
            long interval = 1;
            if (rt) {
                List<String> newFileNames = null;
                Jedis jedis = null;
                jedis = redisClient.getJedis();
                if (null == jedis) {
                    logger.error("无法获取Jedis实例");
                    apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS11));
                    apiResult.setErrormsg("其他内部错误(无法获取Jedis实例)");
                    apiResult.setData("");
                    apiResult.setEntirety_time("");
                    apiResult.setLib_time("");
                    return apiResult;
                }
                Jedis finalJedis = jedis;
                boolean bolnew = false;
                boolean bolnewN = true;
                while (bolnewN) {
                    Date date2 = new Date();
                    interval = (date2.getTime() - date1.getTime()) / 1000;
                    logger.info("超时时间秒数：" + interval + "s");
                    //默认超时时间为30秒
                    if (interval > AppConstant.MAX_CODE_OVERTIME) {
                        apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS05));
                        apiResult.setErrormsg("请求过期");
                        apiResult.setData("");
                        apiResult.setEntirety_time("20000");
                        apiResult.setLib_time("0");
                        boltrue = false;
                        break;
                    }
                    Thread.sleep(1000);
                    Set<Tuple> tupleSet = redisClient.zrangeWithScore(SYNC_FTP_FILE_INDEX, 0, -1);
                    for (Tuple tuple : tupleSet) {
                        if (tuple.getElement().toString().equals(fileName)) {
                            bolnew = true;
                            finalJedis.zremrangeByScore(SYNC_FTP_FILE_INDEX,tuple.getScore(),tuple.getScore());
                            bolnewN=false;
                            break;
                        }
                    }
                }

                if (bolnew) {
                    InputStream input = null;
                    pooledObjectN = dexFtpClientN.get();
                    FTPClient ftpClient = pooledObjectN.getObject();
                    ftpClient.setFileType(FTPClient.ASCII_FILE_TYPE);
                    ftpClient.enterLocalPassiveMode();
                    while (boltrue) {
                        Date date2 = new Date();
                        interval = (date2.getTime() - date1.getTime()) / 1000;
                        logger.info("超时时间秒数：" + interval + "s");
                        //默认超时时间为30秒
                        if (interval > AppConstant.MAX_CODE_OVERTIME) {
                            apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS05));
                            apiResult.setErrormsg("请求过期");
                            apiResult.setData("");
                            apiResult.setEntirety_time("20000");
                            apiResult.setLib_time("0");
                            boltrue = false;
                            break;
                        } else {

                            input = ftpClient.retrieveFileStream("/" + fileName);
                            if (null == input) {
                                logger.info("未发现这个目录下的文件：" + "/" + fileName);
                                boltrue = true;

                                continue;
                            } else {
                                JSONObject m = null;
                                try {
                                    logger.info("发现这个目录下的文件：" + "/" + fileName);
                                    BufferedInputStream bis = null;
                                    StringBuilder buffer = new StringBuilder();
                                    bis = new BufferedInputStream(input);
                                    buffer.delete(0, buffer.length());
                                    byte tmp[] = new byte[1024];
                                    int byteRead;
                                    while ((byteRead = bis.read(tmp)) > 0) {
                                        buffer.append(new String(tmp, 0, byteRead));
                                    }
                                    try {
                                        m = (JSONObject) JSONObject.parse(String.valueOf(buffer));
                                    } catch (Exception e) {
                                        m = null;
                                    }
                                    if (m.get("status").toString().equals(String.valueOf(AppConstant.ERR_CODE_SMHS200).trim())) {
                                        //成功返回1:1内网数据
                                        apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS200));
                                        apiResult.setErrormsg("认证成功");
                                        apiResult.setData(m.get("temp1").toString());
                                    } else if (m.get("status").toString().equals(String.valueOf(AppConstant.ERR_CODE_SMHS02).trim())) {
                                        apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS02));
                                        apiResult.setErrormsg("获取证件照失败");
                                        apiResult.setData("");
                                    } else if (m.get("status").toString().equals(String.valueOf(AppConstant.ERR_CODE_SMHS01).trim())) {
                                        apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS111));
                                        apiResult.setErrormsg("内网照片验证失败");
                                        apiResult.setData("");
                                    } else {
                                        //成功返回1:1内网数据
                                        apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS200));
                                        apiResult.setErrormsg("认证成功");
                                        apiResult.setData("");
                                    }
                                    Date date3 = new Date();
                                    interval = (date3.getTime() - date1.getTime()) / 1000;
                                    apiResult.setEntirety_time(String.valueOf(interval * 1000));
                                    apiResult.setLib_time(m.get("libtime").toString());
                                    boltrue = false;
                                    //删除文件
                                    int i = ftpClient.dele("/" + fileName);
                                    logger.info(fileName + "文件删除成功:" + i);
                                    break;
                                } catch (Exception ex) {
                                    logger.info("目录下内容处理报错：" + "/" + ex.getMessage());
                                    break;
                                }
                            }
                        }
                    }
                }
                logger.info("退出while");
                return apiResult;
            } else {
                apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS11));
                apiResult.setErrormsg("其他内部错误(请求入外网数据库失败)");
                apiResult.setData("");
                apiResult.setEntirety_time("");
                apiResult.setLib_time("");
                return apiResult;
            }
        } catch (Exception ex) {
            apiResult.setErrorcode(String.valueOf(AppConstant.ERR_CODE_SMHS11));
            apiResult.setErrormsg("其他内部错误:" + ex.getMessage());
            apiResult.setData("");
            apiResult.setEntirety_time("");
            apiResult.setLib_time("");
            return apiResult;
        } finally {
            try {
                dexFtpClient.close(pooledObject);
                dexFtpClientN.close(pooledObjectN);
            } catch (Exception ex) {
                logger.error("释放FTP连接错误", ex);
            }
        }
    }


    /*
   * 将时间戳转换为时间
   */
    public static String stampToDate(String s) {
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long lt = new Long(s);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }

}
